package com.erpoa.service.impl;

import com.alibaba.fastjson.JSON;
import com.erpoa.annotation.DataBase;
import com.erpoa.constants.DataSourceNames;
import com.erpoa.entity.PackMessage;
import com.erpoa.entity.RecMatEntity;
import com.erpoa.mapper.GoodRetMaterialMapper;
import com.erpoa.service.BatchUtilService;
import com.erpoa.service.GoodRetMaterialService;
import com.erpoa.utils.PDAException;
import com.erpoa.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @author chenjimin
 * @Title: GoodRetMaterialServiceImpl
 * @ProjectName oaerp
 * @Description: TODO
 * @date 2020/9/2213:06
 */
@Service
public class GoodRetMaterialServiceImpl implements GoodRetMaterialService {
    private static final Logger logger = LoggerFactory.getLogger(GoodRetMaterialServiceImpl.class);
    @Autowired
    private GoodRetMaterialMapper goodRetMaterialMapper;

    @Autowired
    private BatchUtilService batchUtilService;

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public List<RecMatEntity> functionGetOrderPlan(PackMessage packMessage) {
        // 0、判断条码是否存在
        List<RecMatEntity> entitys = this.goodRetMaterialMapper.selectFbatchExistsByParam(packMessage.getLibrary(),
                packMessage.getUser().getsCode(), packMessage.getMachine());
        if (StringUtil.isEmpty(entitys)) {
            throw new PDAException("没有符合条件的数据");
        }
        return entitys;
    }

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public synchronized RecMatEntity functionSubRecMat(PackMessage packMessage) {
        RecMatEntity recMatEntity = JSON.parseObject(packMessage.getMessage(), RecMatEntity.class);
        RecMatEntity ent = new RecMatEntity();
        String opType = "退料";
        //增加判断工单已结案
        int countsfb = this.goodRetMaterialMapper.countSfb04ByOrderNo(recMatEntity.getfOrderNo());
        if (countsfb > 0) {
            throw new PDAException("该工单已结案，请联系相关计划！");
        }
        // 0、判断料号是不相符
        int countfid = this.goodRetMaterialMapper.countFidByParam(recMatEntity.getfPlanID(), recMatEntity.getfBarCode());
        if (countfid <= 0) {
            throw new PDAException("该批次未用于所选排程");
        }
        // 1.判断应退量是否为0 ，是否可以继续退料
        Double weight = this.goodRetMaterialMapper.selectWeightByParam(recMatEntity.getfPlanID(), recMatEntity.getfType());
        if (weight <= 0) {
            throw new PDAException("应退量小于等于0 ，不能退料");
        }
        // 2 判断总发料量和此次退料量是否会造成ERP中余量下于0.009
        // 0、获取退料的领退料详细和领退料ID
        HashMap dffwcodeTemp = this.goodRetMaterialMapper.selectDFFWCodeByParam(recMatEntity.getfPlanID(), recMatEntity.getfBarCode());
        if (StringUtil.isEmpty(dffwcodeTemp)) {
            throw new PDAException("获取领退料明细数据失败，请确认！");
        }
        String detailID = dffwcodeTemp.get("FID") == null ? "" : dffwcodeTemp.get("FID").toString();
        ent.setfRecID(dffwcodeTemp.get("FPARENTID") == null ? "" : dffwcodeTemp.get("FPARENTID").toString());
        String fFactoryCode = dffwcodeTemp.get("FFACTORYCODE") == null ? "" : dffwcodeTemp.get("FFACTORYCODE").toString();
        String fWorkShopCode = dffwcodeTemp.get("FWORKSHOPCODE") == null ? "" : dffwcodeTemp.get("FWORKSHOPCODE").toString();
        // 1.查询出条码所对应的流转余量
        double unQty = this.goodRetMaterialMapper.selectQtypsqByParam(recMatEntity.getfPlanID(), recMatEntity.getfBarCode());
        if (unQty < recMatEntity.getfWeight()) {
            throw new PDAException("此次流转会超过该批次可流转余量");
        }
        // 2取出所对应的仓库和库位
        HashMap imatemps = this.goodRetMaterialMapper.selectWareHouseByFrecId(ent.getfRecID());
        if (StringUtil.isEmpty(imatemps)) {
            throw new PDAException("未查询出对应的仓库和库位");
        }
        ent.setfWareCode(imatemps.get("TC_IMAM08") == null ? "" : imatemps.get("TC_IMAM08").toString());
        ent.setfSeatCode(imatemps.get("TC_IMAM09") == null ? "" : imatemps.get("TC_IMAM09").toString());

        // 生成新的退料条码
        ent.setfBarCode(recMatEntity.getfBarCode().split("/")[0]);
        for (int i = 1, len = recMatEntity.getfBarCode().split("/").length; i < len; i++) {
            if (i == 3) {
                ent.setfBarCode(ent.getfBarCode() + "/" + String.valueOf(recMatEntity.getfRspQty()));
            } else {
                ent.setfBarCode(ent.getfBarCode() + "/" + recMatEntity.getfBarCode().split("/")[i]);
            }
        }
        // 查看退料条码是否有对应数据
        String batchID = this.goodRetMaterialMapper.selectFidByParam(ent.getfBarCode(), fFactoryCode, fWorkShopCode);
        // 查询是否存在超领,如果存在,报错不允许退料 liujiajie 20190108
        HashMap matproTemp = this.goodRetMaterialMapper.selectmatproByFrecId(ent.getfRecID());
        if (StringUtil.isEmpty(matproTemp)) {
            throw new PDAException("料号不存在!");
        }
        String matCode = matproTemp.get("FMATCODE") == null ? "" : matproTemp.get("FMATCODE").toString();
        String procss = matproTemp.get("FPROCSS") == null ? "" : matproTemp.get("FPROCSS").toString();
        if (!matCode.equals("") && !procss.equals("")) {
            int count2 = this.goodRetMaterialMapper.countsfaByParam(recMatEntity.getfOrderNo(), matCode, procss);
            if (count2 > 0) {
                throw new PDAException("该工单下此料存在超领，不允许正常退料，请先超退！");
            }
        } else {
            throw new PDAException("料号不存在!");
        }
        double originalQty = recMatEntity.getfWeight();// 原发料数量
        float adjustQty = 0;//调整数量
        float difQty = 0; //差异数量
        if ("油墨".equals(recMatEntity.getfType()) || "硅油".equals(recMatEntity.getfType())) {
            // 退料向上取整（仅针对墨水和硅油）
            List<Float> tlQty = batchUtilService.getErpMargin(recMatEntity, "批次退料");
            if (!tlQty.isEmpty() && tlQty != null) {
                difQty = tlQty.get(0);
                adjustQty = tlQty.get(1);
            } else {
                originalQty = recMatEntity.getfWeight();
            }
        }
        String uuId = UUID.randomUUID().toString();
        // 1更新/新增收料明细表
        if (batchID == null || "".equals(batchID)) {
            String batchMatID = UUID.randomUUID().toString();

            int effectRowNum = this.goodRetMaterialMapper.insertBatchMatByParam(batchMatID, ent.getfBarCode(), recMatEntity.getfRspQty(), recMatEntity.getfBarCode(),
                    fFactoryCode, fWorkShopCode);
            if (effectRowNum <= 0) {
                throw new PDAException("插入批次条码数据失败,该条码可能不存在!");
            }
            // 记录每次更新的批次发料数量
            int recordCount = this.goodRetMaterialMapper.insertMgBatchrecodeByParam(UUID.randomUUID().toString(), batchMatID, ent.getfBarCode(),
                    recMatEntity.getfRspQty(), packMessage.getUser().getsCode(), recMatEntity.getfType(), fFactoryCode, fWorkShopCode);
            if (recordCount <= 0) {
                throw new PDAException("插入批次库存记录的数据失败!");
            }
        } else {
            int effectRowNum = this.goodRetMaterialMapper.updateBatchMatByParam(recMatEntity.getfRspQty(), batchID);
            if (effectRowNum <= 0) {
                throw new PDAException("更新批次条码数据失败!");
            }
            // 记录每次更新的批次发料数量
            int recordCount = this.goodRetMaterialMapper.insertBatchMatByParams(UUID.randomUUID().toString(), recMatEntity.getfRspQty(),
                    packMessage.getUser().getsCode(), recMatEntity.getfType(), batchID);
            if (recordCount <= 0) {
                throw new PDAException("插入批次库存记录的数据失败!");
            }
        }
        // 2 插入领退料表
        String recMatID = UUID.randomUUID().toString();

        int updateNum = this.goodRetMaterialMapper.insertRecmatByParam(recMatID, opType, packMessage.getUser().getsCode(),
                originalQty, ent.getfWareCode(),
                ent.getfSeatCode(), ent.getfRecID());
        if (updateNum <= 0) {
            throw new PDAException("写入退料表失败!");
        }

        // 3 插入调拨领退料明细表

        updateNum = this.goodRetMaterialMapper.insertDetailByParam(uuId, packMessage.getUser().getsCode(),
                originalQty, ent.getfWareCode(), ent.getfSeatCode(), recMatID, ent.getfBarCode(), recMatEntity.getfRspQty(), detailID);
        if (updateNum <= 0) {
            throw new PDAException("写入退料详细表失败!");
        }
        // 4 插入条码表
        updateNum = this.goodRetMaterialMapper.insertBarCodeByParam(uuId, recMatEntity.getfModelNo(), originalQty,
                packMessage.getUser().getsCode(), recMatEntity.getfBatch(), recMatEntity.getfVenderCode(), recMatEntity.getfType(),
                recMatEntity.getfColor(), ent.getfBarCode(), recMatEntity.getfPlanID());
        if (updateNum <= 0) {
            throw new PDAException("写入条码表失败!");
        }

        int countslog = 0;
        // 插入tc_x5_logfile 记录表 liujiajie 2019-01-26

        if (adjustQty != 0 && difQty != 0) {
            countslog = this.goodRetMaterialMapper.insertX5LOGByParam(ent.getfWareCode(), ent.getfSeatCode(), adjustQty,
                    packMessage.getUser().getsCode(), ent.getfBarCode(), uuId, ent.getfRecID());
        } else {
            countslog = this.goodRetMaterialMapper.insertX5LOGByParam(ent.getfWareCode(), ent.getfSeatCode(), originalQty,
                    packMessage.getUser().getsCode(), ent.getfBarCode(), uuId, ent.getfRecID());
        }
        if (countslog <= 0) {
            throw new PDAException("写入log记录表失败!");
        }
        int counts = 0;
        // 5 插入中间表
        if (adjustQty != 0) {
            counts = this.goodRetMaterialMapper.insertX5ByParam(ent.getfWareCode(), ent.getfSeatCode(), adjustQty,
                    packMessage.getUser().getsCode(), ent.getfBarCode(), uuId, ent.getfRecID());
        } else {
            counts = this.goodRetMaterialMapper.insertX5ByParam(ent.getfWareCode(), ent.getfSeatCode(), originalQty,
                    packMessage.getUser().getsCode(), ent.getfBarCode(), uuId, ent.getfRecID());
        }

        if (counts <= 0) {
            throw new PDAException("写入中间表失败!");
        }

        return ent;
    }

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public RecMatEntity functionGetQty(PackMessage packMessage) {
        RecMatEntity recMatEntity = JSON.parseObject(packMessage.getMessage(), RecMatEntity.class);
        // 0、计算余量
        RecMatEntity entity = this.goodRetMaterialMapper.selectFweightByParam(recMatEntity.getfPlanID(), recMatEntity.getfType());
        return entity;
    }
}
